package deepr.lib;

import deepr.core.DisposeContext;
import deepr.core.PropertyData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class FilterLib {


  // [{"category":xxx,"levelA":xxx,"levelB":xxx},{"category":xxx,"levelA":xxx,"levelB":xxx}]
  // {"category":x,"levelA":xx} -> "category":x,"levelA":xx
  public static StringBuilder joinJsonKeyValue(String property, Object value) {
    Assert.isTrue(value instanceof HashMap, property + " value must be hashMap");
    HashMap<String, Object> v = (HashMap<String, Object>) value;
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<String, Object> entry : v.entrySet()) {
      appendJoiner(sb, ",");
      sb.append(entry.getKey()).append(":").append(entry.getValue());
    }
    return sb;
  }

  public static void appendJoiner(StringBuilder sb, String joiner) {
    if (sb.length() > 0)
      sb.append(joiner);
  }

  public static String jsonKeyToInt(String key) {
    return "(" + key + ")::int";
  }


  public static String[] concatJsonKey(String[] keys) {
    StringBuilder str = new StringBuilder();
    StringBuilder prefixKey = new StringBuilder();
    int len = keys.length;
    for (int i = 0; i < len; i++) {
      if (i == len - 1) {
        str.append("->>'").append(keys[i]).append("'");
        prefixKey.append("_").append(keys[i]);
      } else if (i > 0) {
        str.append("->").append(keys[i]);
        prefixKey.append("_").append(keys[i]);
      } else {
        str.append(keys[i]);
        prefixKey.append(keys[i]);
      }
    }
    return new String[]{str.toString(), prefixKey.toString()};
  }

  public static String parseSelectKeys(DisposeContext ctx, HashMap<String, PropertyData> fields, String object, String[] select) throws Exception {
    StringBuilder sb = new StringBuilder();
    for (String s : select) {
      if (sb.length() > 0)
        sb.append(",");
      PropertyData propertyData = fields.get(s);
      log.debug("object: {}, field: {}, fieldInfo: {}", object, s, propertyData);
      if (propertyData != null) {
        Class<?> handler = propertyData.getHandler();
        if (handler != null) {
          sb.append(s).append(":").append(
              handler.getMethod("select",
                  DisposeContext.class, String.class, String.class, Object.class).
                  invoke(handler.newInstance(), ctx, object, s, propertyData.getHandlerArgs()));
        } else
          sb.append(s).append(":").append(object).append(".").append(s);
      } else
        sb.append(s).append(":").append(object).append(".").append(s);
    }
    return sb.toString();
  }

}
